import { v4 as uuidv4 } from 'uuid';
import { Vector2 } from './Vector2';
import {
    Collider,
    ColliderType,
    ColliderState,
    ColliderOptions,
    CollisionResult
} from './types';

/**
 * 基础碰撞体类
 * 实现碰撞体接口的通用功能
 */
export abstract class BaseCollider implements Collider {
    public readonly id: string;
    public readonly type: ColliderType;
    public state: ColliderState;
    public readonly isTrigger: boolean;
    public readonly tag: string;
    public readonly layer: number;
    public readonly offset: Vector2;
    public rotation: number;
    public scale: Vector2;
    public enabled: boolean;
    public position: Vector2;
    public bounds: {
        min: Vector2;
        max: Vector2;
    };
    
    protected constructor(options: ColliderOptions) {
        this.id = uuidv4();
        this.type = options.type;
        this.state = ColliderState.ACTIVE;
        this.isTrigger = options.isTrigger ?? false;
        this.tag = options.tag ?? '';
        this.layer = options.layer ?? 0;
        this.offset = options.offset?.clone() ?? new Vector2();
        this.rotation = options.rotation ?? 0;
        this.scale = options.scale?.clone() ?? new Vector2(1, 1);
        this.enabled = options.enabled ?? true;
        this.position = new Vector2();
        this.bounds = {
            min: new Vector2(),
            max: new Vector2()
        };
    }
    
    /**
     * 更新碰撞体
     */
    public update(position: Vector2, rotation?: number, scale?: Vector2): void {
        this.position = position.clone();
        if (rotation !== undefined) {
            this.rotation = rotation;
        }
        if (scale !== undefined) {
            this.scale = scale.clone();
        }
        this.updateBounds();
    }
    
    /**
     * 检查是否与另一个碰撞体相交
     */
    public abstract intersects(other: Collider): boolean;
    
    /**
     * 检查点是否在碰撞体内
     */
    public abstract contains(point: Vector2): boolean;
    
    /**
     * 获取碰撞体中心点
     */
    public abstract getCenter(): Vector2;
    
    /**
     * 获取碰撞体面积
     */
    public abstract getArea(): number;
    
    /**
     * 克隆碰撞体
     */
    public abstract clone(): Collider;
    
    /**
     * 销毁碰撞体
     */
    public destroy(): void {
        this.state = ColliderState.DISABLED;
        this.enabled = false;
    }
    
    /**
     * 更新碰撞体边界
     */
    protected abstract updateBounds(): void;
    
    /**
     * 检查碰撞体是否有效
     */
    public isValid(): boolean {
        return this.enabled && this.state !== ColliderState.DISABLED;
    }
    
    /**
     * 检查是否可以与另一个碰撞体进行碰撞检测
     */
    protected canCollideWith(other: Collider): boolean {
        return this.isValid() && other.isValid() && this.layer === other.layer;
    }
    
    /**
     * 计算两个碰撞体之间的碰撞结果
     */
    protected abstract calculateCollision(other: Collider): CollisionResult;
    
    /**
     * 将点从世界坐标转换到碰撞体局部坐标
     */
    protected worldToLocal(point: Vector2): Vector2 {
        const local = point.clone().subtract(this.position);
        if (this.rotation !== 0) {
            local.rotate(-this.rotation);
        }
        if (!this.scale.equals(new Vector2(1, 1))) {
            local.divide(this.scale);
        }
        return local.subtract(this.offset);
    }
    
    /**
     * 将点从碰撞体局部坐标转换到世界坐标
     */
    protected localToWorld(point: Vector2): Vector2 {
        const world = point.clone().add(this.offset);
        if (!this.scale.equals(new Vector2(1, 1))) {
            world.multiply(this.scale);
        }
        if (this.rotation !== 0) {
            world.rotate(this.rotation);
        }
        return world.add(this.position);
    }
} 